package com.cml.dm.admin.service.impl;

import cn.hutool.extra.spring.SpringUtil;
import com.cml.dm.admin.entity.DmExeLogger;
import com.cml.dm.admin.entity.DmMetadata;
import com.cml.dm.admin.event.BRNoticeEvent;
import com.cml.dm.admin.service.DmEngineService;
import com.cml.dm.admin.service.TaskExecutorService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
public abstract class AbstractTaskExecutorService  implements TaskExecutorService {
    @Autowired
    private DmEngineService dmEngineService;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Override
    public void execute(DmExeLogger dmExeLogger, Object extParameter) {
        DmMetadata dmMetadata = new DmMetadata();
        dmMetadata.setTaskID(dmExeLogger.getTaskID());
        dmMetadata.setVersion(dmExeLogger.getVersion());
        List<DmMetadata> dmMetadataList = dmEngineService.queryDmMetadata(dmMetadata);
        Map<String, DmMetadata> dmMetadataMap = dmMetadataList.stream().collect(Collectors.toMap(DmMetadata::getNodeId, Function.identity()));
        DmMetadata firstMetadata = null;
        //找到第一个节点，并形成链表
        for (DmMetadata dm:dmMetadataList) {
            if(!StringUtils.isBlank(dm.getJoinNodeId())){
                dm.setJoinNode(dmMetadataMap.get(dm.getJoinNodeId()));
            }
            if(!StringUtils.isBlank(dm.getNext())){
                dm.setNextDmMetadata(dmMetadataMap.get(dm.getNext()));
                dm.getNextDmMetadata().setUpDmMetadata(dm);
            }
            if(dm.getFirst().equals(dm.getNodeId())){
                firstMetadata = dm;
//                dm.visitor(dm,dmMetadataList);
//                break;
            }
        }
        //发送备份、恢复通知
        applicationEventPublisher.publishEvent(BRNoticeEvent.begin(dmExeLogger.getOrgId()));
        try {
            this.doTask(firstMetadata,dmExeLogger,extParameter);
        }finally {
            //任务执行完成
            applicationEventPublisher.publishEvent(BRNoticeEvent.end(dmExeLogger.getOrgId()));
        }
    }

    /**
     * 具体的任务
     * @param dmExeLogger
     * @param extParameter
     */
    public abstract void doTask(DmMetadata dmMetadata, DmExeLogger dmExeLogger, Object extParameter);
}
